<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<script src="../../../resources/js-test.js"></script>
</head>
<body>
<div id="parent">
<select id="sl16" multiple size=5>
<option>a</option>
<option>b</option>
<option>c</option>
<option>d</option>
<option>e</option>
</select>
</div>
<p id="description"></p>
<div id="console"></div>
<script>
description('&lt;select&gt; selection test for mouse events and keyevents.');

function mouseMoveToOption(selId, index) {
    if (!window.eventSender) {
        console.log("Needs eventSender.");
        return;
    }
    var sl = document.getElementById(selId);
    var itemHeight = Math.floor(sl.offsetHeight / sl.size);
    var border = 1;
    var y = border + index * itemHeight;
    eventSender.mouseMoveTo(sl.offsetLeft + border, sl.offsetTop + y - window.pageYOffset);
}

function mouseClickOnSelect(selId, index, modifier) {
    document.getElementById(selId).focus();
    if (window.eventSender) {
        mouseMoveToOption(selId, index);
        eventSender.mouseDown(0, [modifier]);
        eventSender.mouseUp(0, [modifier]);
    }
}

function keyDownOnSelect(selId, identifier, modifier) {
    document.getElementById(selId).focus();
    if (window.eventSender)
        eventSender.keyDown(identifier, [modifier]);
}

function createSelect(idName, sz, mlt, selIndex) {
    var sl = document.createElement("select");
    var i = 0;
    sl.size = sz;
    while (i < sz) {
        var opt = document.createElement("option");
        if (i == selIndex)
            opt.selected = true;
        opt.textContent = "item " + i;
        sl.appendChild(opt);
        i++;
    }
    sl.multiple = mlt;
    sl.id = idName;
    var parent = document.getElementById("parent");
    parent.appendChild(sl);
}

function selectionPattern(selId) {
    var sl = document.getElementById(selId);
    var result = '';
    for (var i = 0; i < sl.options.length; i++)
        result += sl.options[i].selected ? '1' : '0';
    return result;
}

createSelect("sl1", 5, false, -1);
createSelect("sl2", 5, false, 1);
createSelect("sl3", 5, false, -1);
createSelect("sl4", 5, false, 1);
createSelect("sl5", 5, false, 2);
createSelect("sl6", 5, false, 3);
createSelect("sl7", 5, false, 1);

createSelect("sl8", 5, true, -1);
createSelect("sl9", 5, true, 1);
createSelect("sl10", 5, true, -1);
createSelect("sl11", 5, true, 1);
createSelect("sl12", 5, true, 2);
createSelect("sl13", 5, true, 0);
createSelect("sl14", 5, true, 1);
createSelect("sl15", 5, true, 0);

debug("1) Select one item with mouse (no previous selection)");
mouseClickOnSelect("sl1", 0);
shouldBe('selectionPattern("sl1")', '"10000"');

debug("2) Select one item with mouse (with previous selection)");
mouseClickOnSelect("sl2", 0);
shouldBe('selectionPattern("sl2")', '"10000"');

debug("3) Select one item with the keyboard (no previous selection)");
keyDownOnSelect("sl3", "ArrowUp");
shouldBe('selectionPattern("sl3")', '"00001"');

debug("4) Select one item with the keyboard (with previous selection)");
keyDownOnSelect("sl4", "ArrowDown");
shouldBe('selectionPattern("sl4")', '"00100"');

debug("5) Attempt to select an item cmd-clicking");
mouseClickOnSelect("sl5", 1, "addSelectionKey");
shouldBe('selectionPattern("sl5")', '"01000"');

debug("6) Attempt to select a range shift-clicking");
mouseClickOnSelect("sl6", 1, "rangeSelectionKey");
shouldBe('selectionPattern("sl6")', '"01000"');

debug("7) Attempt to select a range with the keyboard");
keyDownOnSelect("sl7", "ArrowDown", "rangeSelectionKey");
shouldBe('selectionPattern("sl7")', '"00100"');

// Multiple selection tests

debug("8) Select one item with mouse (no previous selection)");
mouseClickOnSelect("sl8", 0);
shouldBe('selectionPattern("sl8")', '"10000"');

debug("9) Select one item with mouse (with previous selection)");
mouseClickOnSelect("sl9", 0);
shouldBe('selectionPattern("sl9")', '"10000"');

debug("10) Select one item with the keyboard (no previous selection)");
keyDownOnSelect("sl10", "ArrowUp");
shouldBe('selectionPattern("sl10")', '"00001"');

debug("11) Select one item with the keyboard (with previous selection)");
keyDownOnSelect("sl11", "ArrowDown");
shouldBe('selectionPattern("sl11")', '"00100"');

debug("12) Select an item cmd-clicking");
mouseClickOnSelect("sl12", 1, "addSelectionKey");
shouldBe('selectionPattern("sl12")', '"01100"');

debug("13) Select a range shift-clicking");
mouseClickOnSelect("sl13", 3, "rangeSelectionKey");
shouldBe('selectionPattern("sl13")', '"11110"');

debug("14) Select a range with the keyboard");
keyDownOnSelect("sl14", "ArrowDown", "rangeSelectionKey");
shouldBe('selectionPattern("sl14")', '"01100"');

debug("15) Drag upside-down");
mouseMoveToOption("sl15", 1);
eventSender.dragMode = false; // Avoid event delay in eventSender.
eventSender.mouseDown(0);
shouldBeEqualToString('selectionPattern("sl15")', "01000");
shouldBeEqualToString('mouseMoveToOption("sl15", 3); selectionPattern("sl15")', "01110");
shouldBeEqualToString('mouseMoveToOption("sl15", 2); selectionPattern("sl15")', "01100");
eventSender.mouseUp(0);
// activeSelectionEnd is the third OPTION.  ArrowUp should select the previous
// one of the third OPTION.  Adding new OPTION shouldn't clear
// activeSelectionEnd.
shouldBeEqualToString('sl15.add(new Option("a")); eventSender.keyDown("ArrowUp"); selectionPattern("sl15")', "010000");

debug("16) Active-selection after type-ahead");
shouldBeEqualToString("mouseClickOnSelect('sl16', 1); selectionPattern('sl16')", "01000");
shouldBeEqualToString("keyDownOnSelect('sl16', 'e'); selectionPattern('sl16')", "00001");
shouldBeEqualToString("keyDownOnSelect('sl16', 'ArrowUp', 'rangeSelectionKey'); selectionPattern('sl16')", "00011");

document.getElementById("parent").remove();
</script>
</body>
</html>
